<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>API Documentation</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:rurban@x-ray.at" />
</head>

<body style="background-color: white">


<!-- INDEX BEGIN -->
<div name="index">
<p><a name="__index__"></a></p>

<ul>

  <li><a href="#name">NAME</a></li>
  <li><a href="#description">DESCRIPTION</a></li>
  <li><a href="#options">OPTIONS</a></li>
  <li><a href="#this_tool_s_api">This tool's API</a></li>
  <ul>

    <li><a href="#readproperty">ReadProperty</a></li>
    <ul>

      <li><a href="#inputs_to_readproperty">Inputs to ReadProperty</a></li>
      <li><a href="#outputs_from_readproperty">Outputs from ReadProperty</a></li>
      <li><a href="#example_of_readproperty">Example of ReadProperty</a></li>
    </ul>

    <li><a href="#readpropertymultiple">ReadPropertyMultiple</a></li>
    <ul>

      <li><a href="#inputs_to_readpropertymultiple">Inputs to ReadPropertyMultiple</a></li>
      <li><a href="#outputs_from_readpropertymultiple">Outputs from ReadPropertyMultiple</a></li>
      <li><a href="#example_of_readpropertymultiple">Example of ReadPropertyMultiple</a></li>
    </ul>

    <li><a href="#writeproperty">WriteProperty</a></li>
    <ul>

      <li><a href="#inputs_to_writeproperty">Inputs to WriteProperty</a></li>
      <li><a href="#outputs_from_writeproperty">Outputs from WriteProperty</a></li>
      <li><a href="#example_of_writeproperty">Example of WriteProperty</a></li>
    </ul>

    <li><a href="#timesync">TimeSync</a></li>
    <ul>

      <li><a href="#inputs_to_timesync">Inputs to TimeSync</a></li>
      <li><a href="#outputs_from_timesync">Outputs from TimeSync</a></li>
      <li><a href="#example_of_timesync">Example of TimeSync</a></li>
    </ul>

    <li><a href="#log">Log</a></li>
    <ul>

      <li><a href="#inputs_to_log">Inputs to Log</a></li>
      <li><a href="#example_of_log">Example of Log</a></li>
    </ul>

    <li><a href="#silencelog">SilenceLog</a></li>
    <ul>

      <li><a href="#inputs_to_silencelog">Inputs to SilenceLog</a></li>
      <li><a href="#outputs_from_silencelog">Outputs from SilenceLog</a></li>
      <li><a href="#example_of_silencelog">Example of SilenceLog</a></li>
    </ul>

    <li><a href="#retry">Retry</a></li>
    <ul>

      <li><a href="#inputs_to_retry">Inputs to Retry</a></li>
      <li><a href="#outputs_from_retry">Outputs from Retry</a></li>
      <li><a href="#example_of_retry">Example of Retry</a></li>
    </ul>

  </ul>

</ul>

<hr name="index" />
</div>
<!-- INDEX END -->

<p>
</p>
<h1><a name="name">NAME</a></h1>
<p>bacnet.pl - Scriptable BACnet communications</p>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>This is a tool for scriptable BACnet communication. Users can write their own
scripts using standard Perl syntax and API defined in this tool to perform desired
execution sequences. For details on this tool's API, see Documentation.html. For other
Perl documentation, see <a href="http://perldoc.perl.org">http://perldoc.perl.org</a></p>
<link href="syntax.css" rel="stylesheet" type="text/css">
<script src="jquery.js"></script>
<script src="syntax.js"></script><p>
</p>
<hr />
<h1><a name="options">OPTIONS</a></h1>
<p>Usage: bacnet.pl [program_options] [-- script_args]</p>
<p>This program executes a script in perl syntax to perform BACnet/IP operations.</p>
<pre>

 Possible program options:
   --script=s    The script to execute.
   --log=s       The file to log all output.
   --help        This help message.</pre>
<pre>
 Possible environment variables are:
    BACNET_IFACE - set this value to dotted IP address of the interface (see
         ipconfig) for which you want to bind.  Default is the interface which
         Windows considers to be the default (how???).  Hence, if there is only a
         single network interface on Windows, the applications will choose it, and
         this setting will not be needed.
    BACNET_IP_PORT - UDP/IP port number (0..65534) used for BACnet/IP
         communications.  Default is 47808 (0xBAC0).
    BACNET_APDU_TIMEOUT - set this value in milliseconds to change the APDU
         timeout.  APDU Timeout is how much time a client waits for a response from
         a BACnet device.
    BACNET_BBMD_PORT - UDP/IP port number (0..65534) used for Foreign Device
         Registration.  Defaults to 47808 (0xBAC0).
    BACNET_BBMD_TIMETOLIVE - number of seconds used in Foreign Device
         Registration (0..65535). Defaults to 60000 seconds.
    BACNET_BBMD_ADDRESS - dotted IPv4 address of the BBMD or Foreign Device
         Registrar.</pre>
<p>
</p>
<hr />
<h1><a name="this_tool_s_api">This tool's API</a></h1>
<p>In addition to having all standard Perl flow control, functions, and modules,
the this tool provides an API for performing BACnet communication functions.</p>
<p>
</p>
<h2><a name="readproperty">ReadProperty</a></h2>
<p>This function implements the ReadProperty service. There are no built in retry
mechanisms. NOTE: all enumerations are defined in <em class="file">bacenum.h</em></p>
<p>
</p>
<h3><a name="inputs_to_readproperty">Inputs to ReadProperty</a></h3>
<ul>
  <li><b>devideInstance</b> - the instance number of the device we are reading</li>
  <li><b>objectName</b>     - the enumeration for the object name we are reading</li>
  <li><b>objectInstance</b> - the instance number of the object we are reading</li>
  <li><b>propertyName</b>   - the enumeration  for the property name we are reading</li>
  <li><b>index</b>          - Optional (default -1): the index number we are reading from. -1 if not applicable</li>
</ul><p>
</p>
<h3><a name="outputs_from_readproperty">Outputs from ReadProperty</a></h3>
<ul>
  <li><b>result</b>    - the sting result (value or error) for ReadProperty</li>
  <li><b>isFailure</b> - zero means no failure, non-zero means failure</li>
</ul><p>
</p>
<h3><a name="example_of_readproperty">Example of ReadProperty</a></h3>
<p>The following example will read AV0.PresentValue from device 1234</p>
<pre>
    my ($res, $failed) = ReadProperty(1234, 'OBJECT_ANALOG_VALUE', 0, 'PROP_PRESENT_VALUE');</pre>
<p>
</p>
<h2><a name="readpropertymultiple">ReadPropertyMultiple</a></h2>
<p>This function implements the ReadPropertyMultiple service. There are no built in retry
mechanisms. NOTE: all enumerations are defined in <em class="file">bacenum.h</em></p>
<p>
</p>
<h3><a name="inputs_to_readpropertymultiple">Inputs to ReadPropertyMultiple</a></h3>
<ul>
  <li><b>devideInstance</b> - the instance number of the device we are reading</li>
  <li><b>r_answerList</b>   - reference to a list where to store the answers</li>
  <li><b>list</b>           - a list of ReadAccessSpecifications</li>
  <ul>
    <li><b>objectType</b>     - the enumeration for the object name to read from</li>
    <li><b>objectInstance</b> - the instance number of the object we are reading</li>
    <li><b>propertyName</b>   - the enumeration  for the property name we are reading</li>
    <li><b>index</b>          - the index number we are reading from. Use -1 if not applicable</li>
  </ul>
</ul><p>
</p>
<h3><a name="outputs_from_readpropertymultiple">Outputs from ReadPropertyMultiple</a></h3>
<ul>
  <li><b>result</b>    - the 'QQQ' delimited concatenated sting result (value or error) for ReadPropertyMultiple. The parsed out result is returned in r_answerList</li>
  <li><b>isFailure</b> - zero means no failure, non-zero means failure</li>
</ul><p>
</p>
<h3><a name="example_of_readpropertymultiple">Example of ReadPropertyMultiple</a></h3>
<p>The following example will read AV0.PresentValue and AV1.PresentValue from device 1234</p>
<pre>
    my @RPM_request = ();
    my @RPM_answer = ();
    my $failed;
    push @RPM_request, ['OBJECT_ANALOG_VALUE', 0, 'PROP_PRESENT_VALUE', -1];
    push @RPM_request, ['OBJECT_ANALOG_VALUE', 1, 'PROP_PRESENT_VALUE', -1];
    (undef, $failed) = ReadPropertyMultiple(1234, \@RPM_answer, @RPM_request);</pre>
<p>
</p>
<h2><a name="writeproperty">WriteProperty</a></h2>
<p>This function implements the WriteProperty service. There are no built in retry
mechanisms. NOTE: all enumerations are defined in <em class="file">bacenum.h</em></p>
<p>
</p>
<h3><a name="inputs_to_writeproperty">Inputs to WriteProperty</a></h3>
<ul>
  <li><b>devideInstance</b> - the instance number of the device we are writing</li>
  <li><b>objectName</b>     - the enumeration for the object name we are writing</li>
  <li><b>objectInstance</b> - the instance number of the object we are writing</li>
  <li><b>propertyName</b>   - the enumeration for the property name we are writing</li>
  <li><b>tagName</b>        - the enumeration for the type of value we are writing. To specify context tags, prepend the tag name with "Cn:" where 'n' is the context number.</li>
  <li><b>value</b>          - the value we are writing</li>
  <li><b>priority</b>       - Optional (default 0): the priority within Priority Array to write at. Use 1-16 when specify priority, 0 to not specify priority.</li>
  <li><b>index</b>          - Optional (default -1): the index within an array we are writing to. Use positive number to indicate index, -1 to not specify index.</li>
</ul><p>
</p>
<h3><a name="outputs_from_writeproperty">Outputs from WriteProperty</a></h3>
<ul>
  <li><b>result</b>    - the sting result (value or error) for WriteProperty</li>
  <li><b>isFailure</b> - zero means no failure, non-zero means failure</li>
</ul><p>
</p>
<h3><a name="example_of_writeproperty">Example of WriteProperty</a></h3>
<p>The following example will write 1.0 to AV0.PresentValue in device 1234</p>
<pre>
    my ($res, $failed) = WriteProperty(1234, 'OBJECT_ANALOG_VALUE', 0, 'PROP_PRESENT_VALUE', 'BACNET_APPLICATION_TAG_REAL', 1.0);</pre>
<p>
</p>
<h2><a name="timesync">TimeSync</a></h2>
<p>This function implements the TimeSync and UTCTimeSync services</p>
<p>
</p>
<h3><a name="inputs_to_timesync">Inputs to TimeSync</a></h3>
<ul>
    <li><b>deviceInstanceNumber</b> - the instance number of the device we are  reading</li>
    <li><b>year</b>                 - Year (i.e. 2011)</li>
    <li><b>month</b>                - Month (i.e. 11 for November)</li>
    <li><b>day</b>                  - Day (i.e. 1 for first of month)</li>
    <li><b>hour</b>                 - Hour (i.e. 23 for 11pm)</li>
    <li><b>minute</b>               - Minute (i.e. 0-59)</li>
    <li><b>second</b>               - Second (i,e. 0-59)</li>
    <li><b>utcOffset</b>            - Optional: if specified defines the UTC offset and forces UTCTimeSync</li>
</ul><p>
</p>
<h3><a name="outputs_from_timesync">Outputs from TimeSync</a></h3>
<ul>
  <li><b>isFailure</b> - zero means no failure, non-zero means failure</li>
</ul><p>
</p>
<h3><a name="example_of_timesync">Example of TimeSync</a></h3>
<pre>
    $isFailure = TimeSync($deviceInstance, $1, $2, $3, $4, $5, $6) unless $isFailure;</pre>
<p>
</p>
<h2><a name="log">Log</a></h2>
<p>This function prints out to the desired method of logging (STDOUT or file).
NewLine characters are not required when making calls to this function. If any
NewLine characters are specified, they will be stripped out. To print an empty
line, pass in a space as the message. NOTE: This function will honor previous
requests to silence the log (see SilcenseLog for details)</p>
<p>
</p>
<h3><a name="inputs_to_log">Inputs to Log</a></h3>
<ul>
  <li><b>msg</b> - the message to output
</ul><p>
</p>
<h3><a name="example_of_log">Example of Log</a></h3>
<p>The following example will print out &quot;hello world&quot;</p>
<pre>
    Log(&quot;Hello World&quot;);</pre>
<p>
</p>
<h2><a name="silencelog">SilenceLog</a></h2>
<p>This function requests that all future log messages be either suppressed or
enabled.</p>
<p>
</p>
<h3><a name="inputs_to_silencelog">Inputs to SilenceLog</a></h3>
<ul>
  <li><b>logIsQuiet</b> - zero means print to log, non-zero means supress log
</ul><p>
</p>
<h3><a name="outputs_from_silencelog">Outputs from SilenceLog</a></h3>
<p>The previous value of whether or not the log was silenced before caling this
function.</p>
<p>
</p>
<h3><a name="example_of_silencelog">Example of SilenceLog</a></h3>
<p>The following example will print out &quot;hello&quot;, but not &quot;world&quot;</p>
<pre>
    Log(&quot;Hello&quot;);
    SilenceLog(1);
    Log(&quot;World&quot;);</pre>
<p>
</p>
<h2><a name="retry">Retry</a></h2>
<p>This function will try to execute the requested command up to specified number
of times, awaiting the requested answer, with a specified pause between
retries.  NOTE: the only functions which can be executed by this function are
ones which return two parameres in the form of ($response, $isFailure)</p>
<p>
</p>
<h3><a name="inputs_to_retry">Inputs to Retry</a></h3>
<ul>
  <li><b>r_func</b>        - The reference to the function which is to be retried</li>
  <li><b>r_funcArgs</b>    - A reference to an array of arguments for the function to be executed</li>
  <li><b>desiredOutput</b> - The condition which will terminate the retrying. Can be either a number or a regexp to patch against the $response return of the function</li>
  <li><b>maxTries</b>      - The maximum number of retry attempts before calling it quits</li>
  <li><b>sleepSeconds</b>  - The number of seconds (could be fractional) to wait between retries</li>
</ul><p>
</p>
<h3><a name="outputs_from_retry">Outputs from Retry</a></h3>
<ul>
  <li><b>$resp</b>     - The response from the last execution of requested function</li>
  <li><b>isFailure</b> - zero means no failure, non-zero means failure</li>
</ul><p>
</p>
<h3><a name="example_of_retry">Example of Retry</a></h3>
<p>The following example will execute the ReadProperty function to read a property
from an object (see ReadProperty for details on those arguments) with up to
$maxRetries retries (with $retryDelay delay between retries) or unitl the
desired answer of 42 is received.</p>
<pre>
    my ($resp, $isFailure) = Retry(
                \&amp;ReadProperty, [$deviceInstance, 'OBJECT_ANALOG_VALUE', 0, 'PROP_PRESENT_VALUE'],
                42, $maxRetries, $retryDelay
              );
    if ($isFailure)
    {
        die &quot;Value was not 42. Last response was '$resp'&quot;;
    }</pre>
<p>The following example will try to execute a WriteProperty (see that function for
details on its arguments) until the write succeeds.</p>
<pre>
    my ($resp, $isFailure) = Retry(
                \&amp;WriteProperty, [$deviceInstance, 'OBJECT_ANALOG_VALUE', 0, 'PROP_PRESENT_VALUE', 'BACNET_APPLICATION_TAG_REAL', 42.0],
                &quot;Acknowledged&quot;, $maxRetries, $retryDelay
              );
    if ($isFailure)
    {
        die &quot;Could not write 42. Last response was '$resp'&quot;;
    }</pre>

</body>

</html>
